package com.sevennotes.classtable.ui.pages

import android.content.Context
import android.net.Uri
import android.util.Log
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.ExperimentalUnitApi
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import androidx.paging.compose.collectAsLazyPagingItems
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.sevennotes.classtable.R
import com.sevennotes.classtable.config.Settings
import com.sevennotes.classtable.model.ClassAmountRecord
import com.sevennotes.classtable.model.ClassRecord
import com.sevennotes.classtable.ui.pages.classtatistics.ClassStatisticsPage
import com.sevennotes.classtable.ui.pages.components.BottomDialog
import com.sevennotes.classtable.ui.pages.components.BottomShareDialog
import com.sevennotes.classtable.ui.pages.components.MyAddFloatingButton
import com.sevennotes.classtable.ui.pages.components.MyFloatingButton
import com.sevennotes.classtable.ui.pages.components.Tables
import com.sevennotes.classtable.ui.pages.editstudent.EditStudentPage
import com.sevennotes.classtable.ui.pages.littlepages.ClassAmountPage
import com.sevennotes.classtable.ui.pages.littlepages.GpPage
import com.sevennotes.classtable.ui.pages.main_screen.MainScreenPad
import com.sevennotes.classtable.ui.pages.main_screen.MainViewModel
import com.sevennotes.classtable.ui.pages.recordpage.RecordPage
import com.sevennotes.classtable.ui.pages.recordpage.RecordStatisticsPage
import com.sevennotes.classtable.ui.pages.saverecordpage.SaveClassRecordState
import com.sevennotes.classtable.ui.pages.student_history.StudentHistoryPage
import com.sevennotes.classtable.ui.pages.studentlist.StudentsListPage
import com.sevennotes.classtable.ui.pages.tablelist.TableNameScreen
import com.sevennotes.classtable.utils.CommonUtils
import com.sevennotes.classtable.utils.ExcelUtil
import com.sevennotes.classtable.utils.contentColor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

object NavPage {
  const val TABLE_SCREEN = "main_screen"
  const val EDIT_STU_PAGE = "add_stu_page"
  const val STUDENTS_PAGE = "students_page"
  const val CLASS_STATISTICS = "class_statistics"
  const val TABLE_NAME_LIST = "table_name_list"
  const val SAVE_RECORD_PAGE = "save_record_page"
  const val SETTING_PAGE = "setting_page"
  const val RECORD_PAGE = "record_page"
  const val GP_RECORD_PAGE = "gp_record_page"
  const val CLASS_AMOUNT_PAGE = "class_amount_page"
  const val STUDENT_HISTORY_PAGE = "student_history_page"
}

@Composable
fun TitleText(title: String) {
  Text(text = title, modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center)
}

@OptIn(
  ExperimentalUnitApi::class, ExperimentalComposeUiApi::class,
  ExperimentalFoundationApi::class
)
@Composable
fun MainNavHost(
  navController: NavHostController,
  mainScreenViewModel: MainViewModel
) {
  val context = LocalContext.current
  val keyboard = LocalSoftwareKeyboardController.current
  var percentVis by remember { mutableStateOf(false) }

  @Composable
  fun GoBackButton() {
    IconButton(
      onClick = {
        keyboard?.hide()
        navController.popBackStack()
      }) {
      Icon(imageVector = Icons.Filled.Close, contentDescription = "back")
    }
  }

  NavHost(navController = navController, startDestination = NavPage.TABLE_SCREEN) {
    composable(route = NavPage.TABLE_SCREEN) {
      val tableNameListState by mainScreenViewModel.tableNameListState.collectAsState()
      val tableNames = tableNameListState.tableNames?.observeAsState()?.value
      MainScreenPad(
        tittle = {
          var titleMenu by remember { mutableStateOf(false) }
          Box(
            modifier = Modifier.clickable { titleMenu = !titleMenu },
            contentAlignment = Alignment.Center
          ) {
            //titleMenu open
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
              //current table name
              val ctname =
                tableNames?.find { it.id == tableNameListState.currentTable }?.name
              TitleText(title = ctname ?: "课程表")
              Icon(
                modifier = Modifier.size(10.dp),
                imageVector = Icons.Filled.KeyboardArrowDown,
                contentDescription = null
              )
            }
            DropdownMenu(
              modifier = Modifier.fillMaxWidth(),
              expanded = titleMenu,
              onDismissRequest = { titleMenu = false },
            ) {
              if (tableNames != null) {
                for (item in tableNames) {
                  val isCurrent = item.id == tableNameListState.currentTable
                  DropdownMenuItem(
                    onClick = {
                      titleMenu = false
                      mainScreenViewModel.changeCurrentTable(item.id!!)
                    },
                    enabled = !isCurrent
                  ) {
                    RadioButton(
                      selected = isCurrent,
                      onClick = {
                        titleMenu = false
                        mainScreenViewModel.changeCurrentTable(item.id!!)
                      })
                    Text(text = item.name)
                  }
                }
              }
            }
          }
        },
        navigationIcon = {
          var menuOpen by remember { mutableStateOf(false) }
          IconButton(onClick = { menuOpen = !menuOpen }) {
            Icon(imageVector = Icons.Filled.Menu, contentDescription = "menu")
          }
          DropdownMenu(
            expanded = menuOpen,
            onDismissRequest = { menuOpen = false }
          ) {
            DropdownMenuItem(onClick = {
              menuOpen = !menuOpen
              navController.navigate(NavPage.CLASS_STATISTICS)
            }) {
              Text(text = "课时统计")
            }
            DropdownMenuItem(onClick = {
              menuOpen = !menuOpen
              mainScreenViewModel.refreshRecordFlow()
              navController.navigate(NavPage.RECORD_PAGE)
            }) {
              Text(text = "历史记录")
            }
            DropdownMenuItem(onClick = {
              menuOpen = !menuOpen
              tableNameListState.editable.value = false
              navController.navigate(NavPage.TABLE_NAME_LIST)
            }) {
              Text(text = "课表管理")
            }
            DropdownMenuItem(onClick = {
              menuOpen = !menuOpen
              navController.navigate(NavPage.SETTING_PAGE)
            }) {
              Text(text = "设置")
            }
          }
        },
        floatingActionButton = {
          MyFloatingButton(onClick = {
            mainScreenViewModel.refreshSaveClassRecordState()
            navController.navigate(NavPage.SAVE_RECORD_PAGE)
          }) {
            Icon(
              modifier = Modifier.size(30.dp),
              painter = painterResource(id = R.drawable.ic___record), contentDescription = null,
              tint = contentColor(MaterialTheme.colors.primary)
            )
          }
        },
        actions = {
          IconButton(onClick = {
            percentVis = !percentVis
          }) {
            Icon(painter = painterResource(id = R.drawable.ic_zoom), contentDescription = null)
          }
          IconButton(onClick = {
            navController.navigate(NavPage.STUDENTS_PAGE)
          }) {
            Icon(
              imageVector = Icons.Filled.Person,
              contentDescription = "Add"
            )
          }
        }
      ) {
        Tables(
          modifier = Modifier.padding(it),
          mainScreenState = mainScreenViewModel.mainScreenState.collectAsState().value,
          percentVis = percentVis,
          onClassItemMoved = { item, x, y ->
            mainScreenViewModel.onClassItemMoved(item.item, x, y)
          },
          onClassItemTapped = {
            mainScreenViewModel.refreshEditStudentState(it.classItem.studentId)
            navController.navigate(route = NavPage.EDIT_STU_PAGE)
          },
          onXpercentChange = { Settings.widthPercent = it },
          onYpercentChange = { Settings.heightPercent = it }
        )
      }
    }

    composable(route = NavPage.EDIT_STU_PAGE) {
      val editStudentState by mainScreenViewModel.editStudentState.collectAsState()
      val studentId = editStudentState.student.id
      MainScreenPad(tittle = { TitleText(title = if (studentId != -1) "学生信息" else "添加学生") },
        navigationIcon = {
          IconButton(
            onClick = {
              if (studentId == -1) {
                mainScreenViewModel.clearUnexistRecords()
              }
              keyboard?.hide()
              navController.popBackStack()
            }) {
            Icon(imageVector = Icons.Filled.Close, contentDescription = "back")
          }
        },
        actions = {
          IconButton(onClick = {
            if (editStudentState.student.name == "") {
              Toast.makeText(context, "请输入学生姓名", Toast.LENGTH_SHORT).show()
            } else {
              navController.popBackStack()
              mainScreenViewModel.applyChanges()
              keyboard?.hide()
            }
          }) {
            Icon(
              imageVector = Icons.Filled.Done,
              contentDescription = "done"
            )
          }
        }
      ) {
        EditStudentPage(
          editStudentState = editStudentState,
          changeStudentInfo = mainScreenViewModel::changeStudentInfo,
          onUpdateClass = mainScreenViewModel::editClass,
          onAddClass = mainScreenViewModel::addClass,
          onDeleteClass = mainScreenViewModel::deleteClass,
          gotoGpRecord = { studentId ->
            mainScreenViewModel.refreshGpState(studentId)
            keyboard?.hide()
            navController.navigate(NavPage.GP_RECORD_PAGE)
          },
          gotoClassAmountRecord = { studentId ->
            mainScreenViewModel.refreshCaState(studentId)
            keyboard?.hide()
            navController.navigate(NavPage.CLASS_AMOUNT_PAGE)
          }
        )
      }
    }

    composable(route = NavPage.STUDENTS_PAGE) {
      val studentsListState by mainScreenViewModel.studentsListState.collectAsState()
      LaunchedEffect(Unit) {
        studentsListState.editable.value = false
      }
      MainScreenPad(
        tittle = { TitleText(title = "学生管理") },
        navigationIcon = { GoBackButton() },
        floatingActionButton = {
          MyAddFloatingButton {
            mainScreenViewModel.refreshEditStudentState(null)
            navController.navigate(NavPage.EDIT_STU_PAGE)
          }
        },
        actions = {
          IconButton(onClick = {
            studentsListState.editable.value = !studentsListState.editable.value
          }) {
            Icon(imageVector = Icons.Filled.Edit, contentDescription = "edit")
          }
        }
      ) {
        StudentsListPage(
          studentsListState = studentsListState,
          keyboard = keyboard,
          onStuClick = {
            keyboard?.hide()
            mainScreenViewModel.refreshEditStudentState(it.id)
            navController.navigate(route = NavPage.EDIT_STU_PAGE)
          },
          onStuDelete = {
            mainScreenViewModel.deleteStudent(it)
          }
        )
      }
    }

    composable(route = NavPage.CLASS_STATISTICS) {
      val mainScreenState = mainScreenViewModel.mainScreenState.collectAsState().value
      MainScreenPad(
        tittle = { TitleText(title = "课时统计") },
        navigationIcon = { GoBackButton() },
        actions = {
          Spacer(modifier = Modifier.width(60.dp))
        }
      ) {
        ClassStatisticsPage(mainScreenState.sortClassList())
      }
    }

    composable(route = NavPage.TABLE_NAME_LIST) {
      val tableNameListState by mainScreenViewModel.tableNameListState.collectAsState()
      TableNameScreen(
        titleText = { TitleText(it) },
        goBackButton = { GoBackButton() },
        tableNameListState = tableNameListState,
        addTableName = mainScreenViewModel::addTableName,
        changeTableName = mainScreenViewModel::changeCurrentTableName,
        copyClasses = mainScreenViewModel::copyClassesFromOtherTable,
        onTableNameSelect = { mainScreenViewModel.changeCurrentTable(it.id!!) },
        onDeleteTableName = mainScreenViewModel::deleteTableName
      )
    }

    composable(route = NavPage.SAVE_RECORD_PAGE) {
      MainScreenPad(
        tittle = { Text("今日记课") },
        navigationIcon = { GoBackButton() },
        actions = {
          IconButton(onClick = {
            navController.popBackStack()
            mainScreenViewModel.applyClassRecords()
            Toast.makeText(context, "课时记录成功!", Toast.LENGTH_SHORT).show()
          }) {
            Icon(
              imageVector = Icons.Filled.Done,
              contentDescription = "done"
            )
          }
        }
      ) {
        val saveClassRecordState by mainScreenViewModel.saveClassRecordState.collectAsState()
        SaveClassRecordState(
          saveClassRecordState = saveClassRecordState,
          updateClassRecord = mainScreenViewModel::updateClassRecordState,
          updateCurrentDay = mainScreenViewModel::refreshSaveClassRecordState
        )
      }
    }

    composable(route = NavPage.SETTING_PAGE) {
      MainScreenPad(
        tittle = { Text(text = "设置") },
        navigationIcon = { GoBackButton() }
      ) {
        val settingsState by mainScreenViewModel.settingsState.collectAsState()
        SettingsPage(
          settingsState = settingsState,
          themeColor = Settings.themeColor,
          onColorChange = { Settings.themeColor = it },
          onBackup = { f, c ->
            mainScreenViewModel.backupFileJson(f, c)
          },
          onRecovery = { f, c ->
            val extensionName = CommonUtils.getFileExtension(context, f)
            Log.d("test", "extension name : $extensionName")
            if (extensionName == "json") {
              mainScreenViewModel.readBackupFileJson(f, c)
            } else if (extensionName == "bin") {
              mainScreenViewModel.readBackupFile(f, c)
            }
          },
          onNetBackup = {
            mainScreenViewModel.netBackupJsonFile(
              fileName = CommonUtils.generateFileNameWithDate("backup_", "json"),
              finish = it
            )
          },
          onNetRecovery = mainScreenViewModel::netReadFile,
          refreshBackupFileList = mainScreenViewModel::refreshBackupFileNames,
          deleteBackupFile = mainScreenViewModel::netDeleteBackupFile
        )
      }
    }

    composable(route = NavPage.RECORD_PAGE) {
      val recordPageState by mainScreenViewModel.recordPageState.collectAsState()
      LaunchedEffect(Unit) {
        recordPageState.editable.value = false
      }
      MainScreenPad(
        tittle = { Text("历史记录") },
        navigationIcon = { GoBackButton() },
        actions = {
          IconButton(onClick = {
            recordPageState.editable.value = !recordPageState.editable.value
          }) {
            Icon(imageVector = Icons.Filled.Edit, contentDescription = "edit")
          }
        }) {
        val classRecordFlow = mainScreenViewModel.classRecordFlow.collectAsLazyPagingItems()
        val classRecordStatis by mainScreenViewModel.classRecordStatisFlowWithFilter.collectAsState(
          emptyList()
        )
        Box(
          modifier = Modifier.fillMaxSize()
        ) {
          val pagerState = rememberPagerState()
          val pagerScope = rememberCoroutineScope()
          var bottomBarHeight by remember { mutableStateOf(0) }
          HorizontalPager(
            modifier = Modifier.padding(bottom = with(LocalDensity.current) { bottomBarHeight.toDp() }),
            pageCount = 2,
            state = pagerState,
            userScrollEnabled = false
          ) { pageIndex ->
            when (pageIndex) {
              0 -> {
                RecordPage(
                  rState = recordPageState,
                  classRecords = classRecordFlow,
                  onSearchValueChange = mainScreenViewModel::changeSearchStr,
                  onFromChange = mainScreenViewModel::changeFromDate,
                  onToChange = mainScreenViewModel::changeToDate,
                  onDelete = { c ->
                    c.classRecord?.let { it -> mainScreenViewModel.deleteClassRecord(it) }
                  },
                  onYearPick = mainScreenViewModel::onRecordSelectedYearChanged,
                  onMonthPick = mainScreenViewModel::onRecordSelectedMonthChanged
                )
              }

              1 -> {
                RecordStatisticsPage(
                  classRecordStatis = classRecordStatis
                )
              }
            }
          }

          BottomNavigation(
            modifier = Modifier
              .align(Alignment.BottomCenter)
              .onGloballyPositioned {
                bottomBarHeight = it.size.height
              }
          ) {
            BottomNavigationItem(
              selected = pagerState.currentPage == 0,
              onClick = {
                pagerScope.launch {
                  pagerState.scrollToPage(0)
                }
              },
              icon = {
                Row(
                  horizontalArrangement = Arrangement.Center,
                  verticalAlignment = Alignment.CenterVertically
                ) {
                  Icon(imageVector = Icons.Filled.List, contentDescription = "list")
                  Text(text = "详细列表")
                }
              }
            )
            BottomNavigationItem(
              selected = pagerState.currentPage == 1,
              onClick = {
                pagerScope.launch {
                  pagerState.scrollToPage(1)
                }
              },
              icon = {
                Row(
                  horizontalArrangement = Arrangement.Center,
                  verticalAlignment = Alignment.CenterVertically
                ) {
                  Icon(imageVector = Icons.Filled.List, contentDescription = "list")
                  Text(text = "年度统计")
                }
              }
            )
          }
        }
      }
    }

    composable(route = NavPage.GP_RECORD_PAGE) {
      val editStudentState = mainScreenViewModel.editStudentState.collectAsState().value
      val gpState by mainScreenViewModel.gpState.collectAsState()
      LaunchedEffect(Unit) {
        gpState.editable.value = false
      }
      MainScreenPad(
        tittle = { Text("积分管理") },
        navigationIcon = { GoBackButton() },
        actions = {
          IconButton(onClick = { gpState.editable.value = !gpState.editable.value }) {
            Icon(imageVector = Icons.Filled.Edit, contentDescription = null)
          }
        }
      ) {
        val student = editStudentState.student
        GpPage(
          gpState = gpState,
          onAdd = {
            mainScreenViewModel.changeStudentInfo(student.copy(gradePoint = student.gradePoint + it.gpChange))
            mainScreenViewModel.addGpRecord(it)
          },
          onDelete = {
            mainScreenViewModel.changeStudentInfo(student.copy(gradePoint = student.gradePoint - it.gpChange))
            mainScreenViewModel.deleteGpRecord(it)
          }
        )
      }
    }

    composable(route = NavPage.CLASS_AMOUNT_PAGE) {
      val editStudentState = mainScreenViewModel.editStudentState.collectAsState().value
      val caState by mainScreenViewModel.caState.collectAsState()
      val historyState by mainScreenViewModel.studentHistoryState.collectAsState()
      val student = editStudentState.student
      val scope = rememberCoroutineScope()
      val caList = caState.caChangeList?.observeAsState()?.value
      LaunchedEffect(student) {
        student.id?.let { mainScreenViewModel.refreshStudentHistoryState(it) }
      }
      LaunchedEffect(Unit) {
        caState.editable.value = false
      }
      val slauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.CreateDocument(),
        onResult = {
          if (it != null) {
            scope.launch {
              val result = saveFileLocal(it, context, historyState.historyList, caList ?: emptyList())
              Toast.makeText(context, if (result) "保存成功！" else "保存失败", Toast.LENGTH_SHORT).show()
            }
          }
        }
      )
      var showShareDialog by remember { mutableStateOf(false) }
      if (showShareDialog) {
        BottomShareDialog(
          onCancel = { showShareDialog = false },
          onWechatClick = {
            showShareDialog = false
            scope.launch {
              shareFileToWechat(
                "${student.name}的课时记录.xlsx",
                context,
                historyState.historyList,
                caList ?: emptyList()
              )
            }
          },
          onLocalClick = {
            showShareDialog = false
            slauncher.launch("${student.name}的课时记录.xlsx")
          }
        )
      }
      MainScreenPad(
        tittle = { Text("课时管理") },
        navigationIcon = { GoBackButton() },
        actions = {
          IconButton(onClick = { caState.editable.value = !caState.editable.value }) {
            Icon(imageVector = Icons.Filled.Edit, contentDescription = null)
          }
        },
        floatingActionButton = {
          FloatingActionButton(
            modifier = Modifier.offset(y = (-50).dp),
            onClick = { showShareDialog = true }
          ) {
            Icon(imageVector = Icons.Filled.Share, contentDescription = "share")
          }
        }
      ) {
        val pagerState = rememberPagerState()
        val pagerScope = rememberCoroutineScope()
        var bottomBarHeight by remember { mutableStateOf(0) }
        Box(
          modifier = Modifier.fillMaxSize()
        ) {
          HorizontalPager(
            modifier = Modifier.padding(bottom = with(LocalDensity.current) { bottomBarHeight.toDp() }),
            pageCount = 2,
            state = pagerState,
            userScrollEnabled = false
          ) { pageIndex ->
            when (pageIndex) {
              0 -> {
                ClassAmountPage(
                  caState = caState,
                  onAdd = {
                    mainScreenViewModel.changeStudentInfo(student.copy(classAmount = student.classAmount + it.amountChange))
                    mainScreenViewModel.addCaRecord(it)
                  },
                  onDelete = {
                    mainScreenViewModel.changeStudentInfo(student.copy(classAmount = student.classAmount - it.amountChange))
                    mainScreenViewModel.deleteCaRecord(it)
                  }
                )
              }

              1 -> {
                StudentHistoryPage(
                  studentName = student.name,
                  state = historyState,
                )
              }
            }
          }

          BottomNavigation(
            modifier = Modifier
              .align(Alignment.BottomCenter)
              .onGloballyPositioned {
                bottomBarHeight = it.size.height
              }
          ) {
            BottomNavigationItem(
              selected = pagerState.currentPage == 0,
              onClick = {
                pagerScope.launch {
                  pagerState.scrollToPage(0)
                }
              },
              icon = {
                Row(
                  horizontalArrangement = Arrangement.Center,
                  verticalAlignment = Alignment.CenterVertically
                ) {
                  Icon(imageVector = Icons.Filled.List, contentDescription = "list")
                  Text(text = "缴费记录")
                }
              }
            )
            BottomNavigationItem(
              selected = pagerState.currentPage == 1,
              onClick = {
                pagerScope.launch {
                  pagerState.scrollToPage(1)
                }
              },
              icon = {
                Row(
                  horizontalArrangement = Arrangement.Center,
                  verticalAlignment = Alignment.CenterVertically
                ) {
                  Icon(imageVector = Icons.Filled.List, contentDescription = "list")
                  Text(text = "历史记录")
                }
              }
            )
          }
        }

      }
    }
  }
}

suspend fun shareFileToWechat(
  fileName: String,
  context: Context,
  classRecordList: List<ClassRecord>,
  classAmountList: List<ClassAmountRecord>
) = withContext(Dispatchers.IO) {
  val file = File(context.filesDir, fileName)
  if (file.exists()) {
    file.delete()
  }
  launch(Dispatchers.Main) {
    Toast.makeText(context, "文件生成中..", Toast.LENGTH_SHORT).show()
  }
  ExcelUtil.writeClassRecordToFile(context, file, classRecordList, classAmountList)
  CommonUtils.shareWechatFriend(context, file)
}

suspend fun saveFileLocal(
  uri: Uri,
  context: Context,
  classRecordList: List<ClassRecord>,
  classAmountList: List<ClassAmountRecord>
): Boolean = withContext(Dispatchers.IO) {
  return@withContext try {
    ExcelUtil.writeClassRecordToFile(context, uri, classRecordList, classAmountList)
    true
  } catch (e: Exception) {
    e.printStackTrace()
    false
  }
}